﻿// Screenshotz
//
// Copyright © Frank Nagl, 2008-2012
// admin@franknagl.de
// www.franknagl.de
//
namespace Screenshotz
{
    using System.Runtime.InteropServices;
    using System;
    using System.Windows.Forms;
    using System.Diagnostics;

    partial class ImageCutForm
    {
        private delegate IntPtr LowLevelKeyboardProc(
            int nCode, IntPtr wParam, IntPtr lParam);

        // ReSharper disable InconsistentNaming
        private const int WH_KEYBOARD_LL = 13;
        // private const int WM_KEYDOWN = 0x0100;
        // ReSharper restore InconsistentNaming
        private const int SleepTime = 500;
        private static readonly LowLevelKeyboardProc Proc = HookCallback;
        //private static IntPtr hookId = IntPtr.Zero;
        private static IntPtr hookId = IntPtr.Zero;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private static IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            //wParam == 260 -> Alt+Print
            //wParam == 256 -> Print
            if (nCode >= 0 && (wParam == (IntPtr)260 && (Keys)vkCode == Keys.PrintScreen ||
                               wParam == (IntPtr)256 && (Keys)vkCode == Keys.PrintScreen))
            {
                //Console.WriteLine("Key: "+(Keys)vkCode);    
                //time(default:400ms) needed, that windows can copy screenshot into the clipboard

                Clipboard.Clear();
                //int i = 0;
                while (!Clipboard.ContainsImage())
                {
                    System.Threading.Thread.Sleep(SleepTime);
                    //    i++;
                }
                Application.OpenForms[0].Visible = true;
                //MessageBox.Show(i.ToString());                
            }

            return CallNextHookEx(hookId, nCode, wParam, lParam);
        }

        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
    }
}
